package com.cro.prison.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cro.prison.common.ErrorBehaviorMethod;
import com.cro.prison.dao.DailyBehaviorDao;
import com.cro.prison.entity.constant.BEHAVIORTYPEENUM_PRISONER;
import com.cro.prison.entity.dto.DailyBehaviorDto;
import com.cro.prison.entity.pojo.DailyBehavior;
import com.cro.prison.entity.pojo.Prisoner;
import com.cro.prison.entity.vo.BehaviorCountVo;
import com.cro.prison.entity.vo.DailyBehaviorVo;
import com.cro.prison.service.DailyBehaviorService;
import com.cro.prison.service.PrisonService;
import com.cro.prison.utils.DateUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.sql.Date;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.stream.Collectors;

@Slf4j
@Service
public class DailyBehaviorServiceImpl  extends ServiceImpl<DailyBehaviorDao, DailyBehavior> implements DailyBehaviorService {

    @Autowired
    ThreadPoolExecutor executor;

    @Autowired
    PrisonService prisonService;

    static Long maxCount = 10L;
    //暂时写死
    static String recordUrl = "../../../../static/test.mp4";
    @Override
    public List<DailyBehaviorVo> getDailyBehavior(Long personId, Date beginDate, Date endDate) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("YYYY-MM-dd");
        //拿到当前日期区间对应的所有异常
        List<DailyBehavior> dailyBehaviorList = this.baseMapper.getDailyBehavior(personId, beginDate, endDate);
        //按照异常类型进行分组
        Map<Integer,List<DailyBehavior>> dailyBehaviorMap = new HashMap();
        for (DailyBehavior dailyBehavior : dailyBehaviorList) {
            List<DailyBehavior> behaviorList = dailyBehaviorMap.getOrDefault(dailyBehavior.getAbnormalBehaviorType(), new ArrayList<>());
            behaviorList.add(dailyBehavior);
            dailyBehaviorMap.put(dailyBehavior.getAbnormalBehaviorType(),behaviorList);
        }
        //判断起始时间和中终止时间
        //第一版代码 ，如果map中 类型不全则前端数据显示有问题，List<DailyBehaviorVo> resultList 中必须包含所有类型的异常
        List<DailyBehaviorVo> result = new ArrayList<>();
        for (BEHAVIORTYPEENUM_PRISONER value : BEHAVIORTYPEENUM_PRISONER.values()) {
            //对于每一种类型,从map中寻找
            DailyBehaviorVo dailyBehaviorVo = new DailyBehaviorVo();
            List<DailyBehavior> currentBehaviors = dailyBehaviorMap.get(value.getCode());
            if(currentBehaviors!= null){
                Map<String,List<Object>> periodBehaviorMap = new HashMap<>();
                for (DailyBehavior dailyBehavior : currentBehaviors) {
                    List<Object> list = periodBehaviorMap.getOrDefault(simpleDateFormat.format(dailyBehavior.getCreateTime()), new ArrayList<>());
                    list.add(dailyBehavior);
                    periodBehaviorMap.put(simpleDateFormat.format(dailyBehavior.getCreateTime()),list);
                }
                dailyBehaviorVo.setType(value.getName());
                dailyBehaviorVo.setBehaviorTimes(ErrorBehaviorMethod.getTimes(beginDate,endDate,periodBehaviorMap));
                dailyBehaviorVo.setPersonId(personId);
            }else{
                //当前类型没有
                dailyBehaviorVo.setType(value.getName());
                dailyBehaviorVo.setPersonId(personId);
                //放入一个全是0的数组
                dailyBehaviorVo.setBehaviorTimes(ErrorBehaviorMethod.getTimes(beginDate,endDate,new HashMap<>()));
            }
            result.add(dailyBehaviorVo);
        }
        return result;
    }
    @Override
    public List<DailyBehaviorVo> getAllDailyBehavior(Date begin, Date end) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("YYYY-MM-dd");
        //拿到当前日期区间对应的所有异常
        List<DailyBehavior> dailyBehaviorList = this.baseMapper.getAllDailyBehavior(begin, end);
        //按照异常类型进行分组
        Map<Integer,List<DailyBehavior>> dailyBehaviorMap = new HashMap();
        for (DailyBehavior dailyBehavior : dailyBehaviorList) {
            List<DailyBehavior> behaviorList = dailyBehaviorMap.getOrDefault(dailyBehavior.getAbnormalBehaviorType(), new ArrayList<>());
            behaviorList.add(dailyBehavior);
            dailyBehaviorMap.put(dailyBehavior.getAbnormalBehaviorType(),behaviorList);
        }
        //判断起始时间和中终止时间
        //第一版代码 ，如果map中 类型不全则前端数据显示有问题，List<DailyBehaviorVo> resultList 中必须包含所有类型的异常
        List<DailyBehaviorVo> result = new ArrayList<>();
        for (BEHAVIORTYPEENUM_PRISONER value : BEHAVIORTYPEENUM_PRISONER.values()) {
            //对于每一种类型,从map中寻找
            DailyBehaviorVo dailyBehaviorVo = new DailyBehaviorVo();
            List<DailyBehavior> currentBehaviors = dailyBehaviorMap.get(value.getCode());
            if(currentBehaviors!= null){
                Map<String,List<Object>> periodBehaviorMap = new HashMap<>();
                for (DailyBehavior dailyBehavior : currentBehaviors) {
                    List<Object> list = periodBehaviorMap.getOrDefault(simpleDateFormat.format(dailyBehavior.getCreateTime()), new ArrayList<>());
                    list.add(dailyBehavior);
                    periodBehaviorMap.put(simpleDateFormat.format(dailyBehavior.getCreateTime()),list);
                }
                dailyBehaviorVo.setType(value.getName());
                dailyBehaviorVo.setBehaviorTimes(ErrorBehaviorMethod.getTimes(begin,end,periodBehaviorMap));
                dailyBehaviorVo.setPersonId(dailyBehaviorVo.getPersonId());
            }else{
                //当前类型没有
                dailyBehaviorVo.setType(value.getName());
                dailyBehaviorVo.setPersonId(dailyBehaviorVo.getPersonId());
                //放入一个全是0的数组
                dailyBehaviorVo.setBehaviorTimes(ErrorBehaviorMethod.getTimes(begin,end,new HashMap<>()));
            }
            result.add(dailyBehaviorVo);
        }
        return result;
    }

    @Override
    public List<BehaviorCountVo> selectByType(Integer prisonerType) {
        List<BehaviorCountVo> list = this.baseMapper.seletByType(prisonerType);
        return list;
    }

    @Override
    public List<BehaviorCountVo> selectByTypeByDate() {
        List<BehaviorCountVo> res;
        //筛选一周内和对应的罪犯
        List<Prisoner> prisonList = prisonService.listByDate();
        List<Long> ids = prisonList.stream().map(Prisoner::getId).collect(Collectors.toList());
        if(ids.size() == 0){
            res = new ArrayList<>();
            res.add(new BehaviorCountVo(1,0));
            res.add(new BehaviorCountVo(2,0));
            res.add(new BehaviorCountVo(3,0));
            return res;
        }
        String id = "";
        for(int i = 0;i<ids.size();i++){
            id += ids.get(i);
            if(i!= ids.size()-1) id+=",";
        }
        res = this.baseMapper.seletByPersonIds(id);
        return res;
    }

    @Override
    public List<BehaviorCountVo> selectAllBehaviorCount() {
        List<BehaviorCountVo> list = this.baseMapper.selectAllBehaviorCount();
        return list;
    }

    @Override
    public List<DailyBehavior> getDailyBehaviorByPersonIdAndDate(Long personId, Date date,Integer type) {
        // 这个时间就是日期往后推一天的结果
        Date dateAfter = new Date(DateUtils.addDay(date,1).getTime());
        return this.baseMapper.selectList(ErrorBehaviorMethod.getQueryByPersonIdAndDate(personId,date,dateAfter,type));
    }

    @Override
    public String getToAnalyseWeb(List<Prisoner> prisonerList)  {
        Prisoner prisoner = getRandomPrisoner(prisonerList);
        Integer type = getRandomBehaviorType();
        String jsonMsg = "";
        List<DailyBehaviorDto> dtoList = this.baseMapper.countDailyBehavior(prisoner.getId(), type);
        if(dtoList != null && !dtoList .isEmpty()){
            Boolean aBoolean = dtoList.size()==1;
            if(aBoolean){
                Long count = dtoList.get(0).getCount();
                DailyBehavior record = new DailyBehavior();
                record.setAbnormalBehaviorType(type);
                Calendar c = Calendar.getInstance();
                record.setCreateTime(c.getTime());
                record.setPersonId(prisoner.getId());
                record.setRecordUrl(recordUrl);
                if( count >= maxCount){
                    jsonMsg = getAdviseByCount(prisoner,type);
                }
                CompletableFuture.supplyAsync(()->{
                    boolean insertBoolean = this.baseMapper.insert(record)>0;
                    return insertBoolean;
                },executor);
                return jsonMsg;
            }
        }
        return jsonMsg;
    }



    /**
     * 根据囚犯和行为类型获取 建议
     * @param prisoner
     * @param type
     * @return
     */
    private String getAdviseByCount(Prisoner prisoner,Integer type){
        StringBuilder advise = new StringBuilder();
        advise.append("囚犯").append(prisoner.getName())
                .append(",编号").append(String.format("%03d",prisoner.getId())).append("近一周")
                .append(BEHAVIORTYPEENUM_PRISONER.getValue(type))
                .append("次数过多,建议进行谈话交流,心理辅导。");
      return advise.toString();
    }

    /**
     * 获取随机一个 异常行为
     */
    private Integer getRandomBehaviorType(){
        BEHAVIORTYPEENUM_PRISONER[] values = BEHAVIORTYPEENUM_PRISONER.values();
        int length = values.length;
        int number = getRandomNumber(length);
        return number;
    }
    /**
     * 从列表中获取随机一个囚犯
     * @param list
     * @return
     */
    private Prisoner getRandomPrisoner(List<Prisoner> list){
        int length = list.size();
        int number = getRandomNumber(length);
        return list.get(number);
    }

    /**
     * 获取 1-length 的随机数
     * @param length
     * @return
     */
    private int getRandomNumber(int length){
        int random = (int)(Math.random()*length)+1;
        while(random>=length || random<0){
            random = (int)(Math.random()*length)+1;
        }
        return random;
    }

}
